﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using Sissonix.ExtRest.RestSchemaModel;
using System.Data.Objects;
using System.Data.SqlClient;
using System.Data.EntityClient;
using MgrModel = Sissonix.ExtRest.RestManagerModel.Model;
using SchModel = Sissonix.ExtRest.RestSchemaModel.Model;
using Sissonix.ExtRest.Exception;

namespace Sissonix.ExtRest.Configuration
{
    /*First thing is to make this class accept the ApplicationStartup control. 
     * It needs to read the web.config for a few things:
     * 1. The connection info for server,dbname,user,pass, and ApplicationName.
     * 2. Loads everything into the static variable app.
     * * Once it does that, next thing is to handle all traffic to the rest root
     * and then read the RestSchema that is in play 
     * */
    public class ExtRestConfigDB
    {
        public static ExtRestConfigDB config { get; set; }
        public static SchModel.Application app { get; set; }

        /// <summary>
        /// Creates the singleton.
        /// </summary>
        static ExtRestConfigDB()
        {
            ExtRestConfigDB.config = new ExtRestConfigDB();
        }

        private ExtRestConfigDB()
        {
            ExtRestConfig webconfig = (ExtRestConfig)(ConfigurationManager.GetSection("ExtRest"));
            if (webconfig == null)
            {
                throw new ExtRest.Exception.RestException("Could not find ExtRest configuration section in the web.config file.");
            }

            string connStr = RestSchemaHelper.BuildEFConnectionString(webconfig.ServerName, webconfig.DatabaseName,
                webconfig.UserId, webconfig.Password);
                
/*                .BuildConnectionString(webconfig.ServerName, webconfig.DatabaseName, 
                webconfig.UserId, webconfig.Password);
            */
            SchModel.RestSchemaEntities ent;
            try
            {
                ent = new SchModel.RestSchemaEntities(connStr);
            }
            catch (System.Exception e)
            {
                throw new RestException("Could not connect to RestSchemaEntities using connstr='" + connStr + "': " + e.Message);
            }

            IQueryable<SchModel.Application> qry = ent.Application
                .Include("Domains.Requests.Errors")
                .Include("ReturnFormat")
                .Where(a => a.ApplicationName == webconfig.AppName);
            
            app = qry.First();
        }

        private string BuildConnectionString(string serverName, string databaseName, string userName, string password) {
            string providerName = "System.Data.SqlClient";

            if (serverName == "" || databaseName == "")
                return "";

            // Initialize the connection string builder for the
            // underlying provider.
            SqlConnectionStringBuilder sqlBuilder = new SqlConnectionStringBuilder();

            // Set the properties for the data source.
            sqlBuilder.DataSource = serverName;
            sqlBuilder.InitialCatalog = databaseName;
            sqlBuilder.UserID = userName;
            sqlBuilder.Password = password;
            
            //sqlBuilder.IntegratedSecurity = true;

            // Build the SqlConnection connection string.
            string providerString = sqlBuilder.ToString();

            // Initialize the EntityConnectionStringBuilder.
            EntityConnectionStringBuilder entityBuilder = new EntityConnectionStringBuilder();

            //Set the provider name.
            entityBuilder.Provider = providerName;

            // Set the provider-specific connection string.
            entityBuilder.ProviderConnectionString = providerString;

            // Set the Metadata location.
            entityBuilder.Metadata = @"res://*/Model.RestSchemaModel.csdl|res://*/Model.RestSchemaModel.ssdl|res://*/Model.RestSchemaModel.msl";
            return entityBuilder.ToString();
        }

        /// <summary>
        /// This static method should be added to the Global.asax
        /// Application_Start() method to make sure that the proper
        /// listeners are added to the route table.
        /// It is add like this:
        ///   ExtRestConfigDB.AppStart();
        /// </summary>
        public static void AppStart() {
            var route = new System.Web.Routing.Route(app.RestRoot + "/{*path}",
                new ExtRest.RestRouteHandler(app.RestRoot));
            System.Web.Routing.RouteTable.Routes.Add(route);
        }
    }
}
